﻿using System;
using System.Collections.Generic;
using UnityEngine;
using Framework.Define;
using Framework.Util;
using Framework.UI;

namespace Framework.Manager
{
    public class UIManager : ManagerBase<UIManager>
    {
        #region Manager通用
        private UIManager() { }
        #endregion

        private Dictionary<CanvasType, Transform> mCanvasDictionary = new Dictionary<CanvasType, Transform>();
        private Dictionary<string, GameObject> mUIDictionary = new Dictionary<string, GameObject>();

        /// <summary>初始化</summary>
        protected override void OnInit()
        {
            AddCanvas("BaseCanvas", CanvasType.BaseCanvas);
            AddCanvas("NormalCanvas", CanvasType.NormalCanvas);
            AddCanvas("PopCanvas", CanvasType.PopCanvas);
        }

        private void AddCanvas(string pSubPath, CanvasType pCanvasType)
        {
            string path = string.Format("{0}/{1}", FrameworkDefine.UICanvasRootPath, pSubPath);
            GameObject canvasGameObjec = UtilCollection.GameObjectUtil.FindOrCreateGameObject(path);
            if (canvasGameObjec != null && !mCanvasDictionary.ContainsKey(pCanvasType))
            {
                mCanvasDictionary.Add(pCanvasType, canvasGameObjec.transform);
            }
        }

        /// <summary>打开UI</summary>
        /// <typeparam name="T">UI类型</typeparam>
        public void OpenUI<T>(Action pCallback = null) where T : Component
        {
            string uiName = GetUIName<T>();
            GameObject uiGameObject = null;
            if (!mUIDictionary.TryGetValue(uiName, out uiGameObject))
            {
                uiGameObject = InstantiateUI<T>();
                if (uiGameObject == null)
                {
                    ManagerCollection.LoadManager.LoadAssetAsync(uiName, (bool pIsSucceeded) =>
                    {
                        OpenUI<T>(pCallback);
                    });
                }
                else
                {
                    uiGameObject.SetActive(true);
                    pCallback?.Invoke();
                }
            }
            else
            {
                uiGameObject.SetActive(true);
                pCallback?.Invoke();
            }
        }

        /// <summary>隐藏UI（不销毁）</summary>
        /// <typeparam name="T">UI类型</typeparam>
        public void HideUI<T>()
        {
            string uiName = GetUIName<T>();
            if (mUIDictionary.ContainsKey(uiName))
            {
                mUIDictionary[uiName].SetActive(false);
            }
        }

        /// <summary>关闭UI（销毁）</summary>
        /// <typeparam name="T">UI类型</typeparam>
        public void CloseUI<T>()
        {
            string uiName = GetUIName<T>();
            if (mUIDictionary.ContainsKey(uiName))
            {
                GameObject uiGameObject = mUIDictionary[uiName];
                mUIDictionary.Remove(uiName);
                GameObject.Destroy(uiGameObject);
            }
        }

        /// <summary>获取ui名称</summary>
        /// <typeparam name="T">ui类型</typeparam>
        private string GetUIName<T>()
        {
            Type type = typeof(T);
            return type.Name;
        }

        /// <summary>实例化UI</summary>
        /// <param name="uiName">面板名称</param>
        /// <param name="gameObjectAsset">资源</param>
        /// <returns>面板对象</returns>
        private GameObject InstantiateUI<T>() where T : Component
        {
            GameObject uiGameObject = null;

            string uiName = GetUIName<T>();
            GameObject gameObjectAsset = ManagerCollection.ResourceManager.GetGameObject(uiName);
            if (gameObjectAsset != null)
            {
                uiGameObject = GameObject.Instantiate(gameObjectAsset);
                IPanelBase panelBase = uiGameObject.AddComponent<T>() as IPanelBase;
                panelBase.Init();

                uiGameObject.transform.SetParent(mCanvasDictionary[panelBase.CanvasType], false);
                uiGameObject.transform.localScale = Vector3.one;
                uiGameObject.transform.localRotation = Quaternion.identity;
                mUIDictionary.Add(uiName, uiGameObject);
            }

            return uiGameObject;
        }
    }
}